package name.williamwall.buxoid;
/**
 * This software is made available under the Gnu General Public License v3
 * and has absolutely no waranty. You may change the software to suit your needs.
 * 
 * Author: William Wall, IV
 */
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class EditTransaction extends Activity {
	private BuxoidDb mDb;
	private Spinner mAccount, mType, mStatus;
	private EditText mAmount, mDesc;
	private AutoCompleteTextView mTags, mLoanTo, mLoanFrom, mSharedBillPayor, mSharedBillPayees;
	private LinearLayout mLoanSection;
	private Button mDate;
	private CheckBox mUpload;
	private String mDateStr;
	private Long mTransId;
	private String mAccountId;
	private int mYear, mMonth, mDay, mAccountPos, mTypePos, mStatusPos;
	private static SimpleDateFormat mReadFormat = new SimpleDateFormat("yyyy M d");
	private static SimpleDateFormat mWriteFormat = new SimpleDateFormat("yyyy-MM-dd");
	private static final String [] TYPES = new String [] {"expense", "income", "loan", "sharedbill"};
	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
//		Log.d("Buxfer", "creating EditTransaction with state " + (icicle == null ? "null": "set"));
		mDb = new BuxoidDb(this);
		mDb.open();
		
		mAccountPos = -1;
		mTypePos = -1;
		mStatusPos = -1;
		
		setContentView(R.layout.edit_trans);
		mAccount = (Spinner) findViewById(R.id.edit_trans_account);
		mType = (Spinner) findViewById(R.id.edit_trans_type);
		mStatus = (Spinner) findViewById(R.id.edit_trans_status);
		mAmount = (EditText) findViewById(R.id.edit_trans_amount);
		mUpload = (CheckBox) findViewById(R.id.edit_trans_upload);
		mDate = (Button) findViewById(R.id.edit_trans_date);
		mDesc = (EditText) findViewById(R.id.edit_trans_desc);
		mTags = (AutoCompleteTextView) findViewById(R.id.edit_trans_tags);
		
		mLoanSection = (LinearLayout) findViewById(R.id.edit_trans_loan);
		mLoanTo = (AutoCompleteTextView) findViewById(R.id.edit_trans_loan_to);
		mLoanFrom = (AutoCompleteTextView) findViewById(R.id.edit_trans_loan_from);
		
		mSharedBillPayor = (AutoCompleteTextView) findViewById(R.id.edit_trans_shared_bill_payor);
		mSharedBillPayees = (AutoCompleteTextView) findViewById(R.id.edit_trans_shared_bill_payees);
		
		mType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                toggleFields(position);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // Do nothing, since the user cannot select nothing in this field
            }
		    
		});
		
		// set the onclick listener for the change date button
		mDate.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				new DatePickerDialog(EditTransaction.this, mDateSetListener, mYear, mMonth-1, mDay).show();
			}
		});
		
		mTransId = icicle != null ? icicle.getLong(BuxoidDb.TRANS_ROWID) : null;
		mAccountId = icicle != null ? icicle.getString(BuxoidDb.TRANS_ACCOUNTID) : null;
		
		if (mTransId == null) {
			Bundle extras = getIntent().getExtras();
			mTransId = extras != null ? extras.getLong(BuxoidDb.TRANS_ROWID): null;
		}
		
		if (mAccountId == null) {
			Bundle extras = getIntent().getExtras();
			mAccountId = extras != null ? extras.getString(BuxoidDb.TRANS_ACCOUNTID): null;
		}
		
		Calendar cal = Calendar.getInstance();
		mYear = cal.get(Calendar.YEAR);
		mMonth = cal.get(Calendar.MONTH) + 1;
		mDay = cal.get(Calendar.DAY_OF_MONTH);
		populateFields();
	}
	
	
	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
//		Log.d("Buxfer", "restore EditTransaction state");
		mTransId = savedInstanceState.getLong(BuxoidDb.TRANS_ROWID);
		mAccountId = savedInstanceState.getString(BuxoidDb.TRANS_ACCOUNTID);
		mAccountPos = savedInstanceState.getInt("accountPos");
		mTypePos = savedInstanceState.getInt("typePos");
		mStatusPos = savedInstanceState.getInt("statusPos");
		
		toggleFields(mTypePos);
	}


	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
//		Log.d("Buxfer", "saving EditTransaction state");
		saveState();
		outState.putLong(BuxoidDb.TRANS_ROWID, mTransId);
		outState.putString(BuxoidDb.TRANS_ACCOUNTID, mAccountId);
		outState.putInt("accountPos", mAccount.getSelectedItemPosition());
		outState.putInt("typePos", mType.getSelectedItemPosition());
		outState.putInt("statusPos", mStatus.getSelectedItemPosition());
	}


	@Override
	protected void onPause() {
		super.onPause();
		saveState();
		mDb.close();
	}

	@Override
	protected void onResume() {
		super.onResume();
		populateFields();
	}
	
	public void populateFields() {
		Cursor cl = mDb.fetchAllTags();
		startManagingCursor(cl);
		
		mTags.setAdapter(new TagListAdapter(this, cl, mDb, false));
		
		Cursor ci = mDb.fetchAllImpacts();
		startManagingCursor(ci);
		
		mLoanFrom.setAdapter(new ImpactListAdapter(this, ci, mDb, false));
		mLoanTo.setAdapter(new ImpactListAdapter(this, ci, mDb, false));
		mSharedBillPayor.setAdapter(new ImpactListAdapter(this, ci, mDb, false));
		mSharedBillPayees.setAdapter(new ImpactListAdapter(this, ci, mDb, true));
		
		Cursor ca = mDb.fetchAllAccounts();
		startManagingCursor(ca);
		
		String [] from = new String [] {
				BuxoidDb.ACCOUNT_NAME
		};
		
		int [] to = new int [] {
			android.R.id.text1
		};
		
		SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, ca, from, to);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		mAccount.setAdapter(adapter);
		
		if (mTransId > 0) {
			// set title
			setTitle("Buxoid: Edit Transaction");
			
			// get transaction
			Cursor c = mDb.fetchTransaction(mTransId);
			
			if (c.getCount() > 0 && c.moveToFirst()) {
			  //TODO: remove
//	            Log.d("Buxfer", c.getString(c.getColumnIndex(BuxoidDb.TRANS_NOTES)));
	            
				// set type field
				String type = c.getString(c.getColumnIndex(BuxoidDb.TRANS_TYPE));
				
				for (int i = 0; i < TYPES.length; i++) {
					if (type.equals(TYPES[i])) {
						mType.setSelection(i);
					}
				}
				
				if (mType.getSelectedItemPosition() == 2) {
				    // parse loan fields from notes
				    String notes = c.getString(c.getColumnIndex(BuxoidDb.TRANS_NOTES));
				    
				    // split on whitespace
				    String[] split = notes.split("\\s");
				    mLoanFrom.setText(split[0]);
				    mLoanTo.setText(split[3]);
				    
				    // set field visibility on
				    mLoanSection.setVisibility(View.VISIBLE);
				} else if (mType.getSelectedItemPosition() == 3) {
				    // parse loan fields from notes
				    String notes = c.getString(c.getColumnIndex(BuxoidDb.TRANS_NOTES));
				    
				    // split on " @@ "
				    String[] firstSplit = notes.split("@@");
				    
				    mSharedBillPayees.setText(firstSplit[1].trim());
				    
				    String[] secondSplit = firstSplit[0].split("\\s");
				    
				    mSharedBillPayor.setText(secondSplit[0]);
				    
				    // set field visibility on
				    mSharedBillPayor.setVisibility(View.VISIBLE);
				    mSharedBillPayees.setVisibility(View.VISIBLE);
				}
				
				// set account spinner
				mAccountId = c.getString(c.getColumnIndex(BuxoidDb.TRANS_ACCOUNTID));
				
				// apparently Spinner.getSelectedItemId doesn't have a corresponding setter
				// to set the position by the row id rather than the position, so get the position.
				int test = mDb.getAccountIdFromBuxid(mAccountId);
				int spinnerPos = 0;
				while(ca.moveToNext()) {
					if (test == ca.getInt(0)) {
						spinnerPos = ca.getPosition();
						break;
					}
				}
				
				mAccount.setSelection(spinnerPos);
				
				// set date
				mDateStr = c.getString(c.getColumnIndex(BuxoidDb.TRANS_DATE));
				
				// set amount field
				mAmount.setText(c.getString(c.getColumnIndex(BuxoidDb.TRANS_AMOUNT)));
				
				// set status field
				mStatus.setSelection(c.getInt(c.getColumnIndex(BuxoidDb.TRANS_STATUS)));
				
				// set upload field
				mUpload.setChecked(c.getInt(c.getColumnIndex(BuxoidDb.TRANS_UPLOAD)) == BuxoidDb.TRANS_DO_UPLOAD);
				
				// set description field
				mDesc.setText(c.getString(c.getColumnIndex(BuxoidDb.TRANS_DESC)));
				
				// set tags field
				mTags.setText(c.getString(c.getColumnIndex(BuxoidDb.TRANS_TAGS)));
			}
		} else {
			setTitle("Buxoid: Add Transaction");
			
			mAccount.setSelection(mAccountPos > -1 ? mAccountPos: 0);
			
			// default type is "expense"
			mType.setSelection(mTypePos > -1 ? mTypePos: 0);
			
			// default status is "pending"
			mStatus.setSelection(mStatusPos > -1 ? mStatusPos: 1);
			
			// default to current date
			try {
				mDateStr = mWriteFormat.format(mReadFormat.parse(mYear + " " + mMonth + " " + mDay));
			} catch (ParseException e) {
			}
		}
		
		mDate.setText(mDateStr);
	}
	
	public void saveState() {
		try {
			mAccountId = mDb.getAccountBuxidFromId(mAccount.getSelectedItemId());
			
			int typePos = mType.getSelectedItemPosition();
			String type = TYPES[typePos];
			double amount = Double.parseDouble(mAmount.getText().toString().trim());
			
			// if amount is negative, assume opposite type and flip amount
			if (amount < 0) {
				amount = -amount;
				type = mType.getSelectedItemId() == 0 ? "income" : "expense";
			}
			
			String status = mStatus.getSelectedItemId() == 0 ? "clear": "pending";
			
			String desc = mDesc.getText().toString().trim();
			String tags = mTags.getText().toString().trim();
			
			// for our purposes, the notes field will hold Loan/Shared bill information until the transaction is uploaded
			String note = null;
			if (typePos == 2) {
			    note = mLoanFrom.getText().toString().trim() + " @@ " + mLoanTo.getText().toString().trim() + " " + amount;
			} else if (typePos == 3) {
			    note = mSharedBillPayor.getText().toString().trim() + " @@ " + mSharedBillPayees.getText().toString().trim();
			}
			
			if (mTransId > 0) {
			    mDb.updateTransaction(mTransId, mAccountId, type, status, desc, mDateStr, tags, note, mUpload.isChecked() ? 1 : 0, amount);
			} else {
				long id = -1;
                try {
                    id = mDb.createTransaction(null, mAccountId, mDateStr, desc, type, tags, note, status, mUpload.isChecked() ? 1 : 0, amount);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
				if (id > 0) {
					mTransId = id;
				}
			}
			
			Toast.makeText(this, "Transaction saved.", Toast.LENGTH_SHORT).show();
		} catch (NumberFormatException e) {}
	}
	
	private void toggleFields(int position) {
	    if (position == 2) {
            // hide the shared bill fields if they are visible
            mSharedBillPayor.setVisibility(View.GONE);
            mSharedBillPayees.setVisibility(View.GONE);
            
            // show the loan fields
            mLoanSection.setVisibility(View.VISIBLE);
        } else if (position == 3) {
            // hide the loan fields
            mLoanSection.setVisibility(View.GONE);
            
            // show the shared bill fields
            mSharedBillPayor.setVisibility(View.VISIBLE);
            mSharedBillPayees.setVisibility(View.VISIBLE);
        } else {
            // hide both
            mLoanSection.setVisibility(View.GONE);
            mSharedBillPayor.setVisibility(View.GONE);
            mSharedBillPayees.setVisibility(View.GONE);
        }
	}
	
	private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            	mYear = year;
            	mMonth = monthOfYear + 1;
            	mDay = dayOfMonth;
            	try {
            		mDateStr = mWriteFormat.format(mReadFormat.parse(mYear + " " + mMonth + " " + mDay));
            	} catch (ParseException e) {
            		
            	}
                mDate.setText(mDateStr);
            }
        };
}
